"use client";

import { useEffect, useState, useCallback, useRef } from "react";
import { motion } from "framer-motion";
import { useToast } from "@/hooks/use-toast";
import { useMobile } from "@/hooks/use-mobile";
import TetrisBoard from "./board";
import TetrisControls from "./controls";
import TetrisPreview from "./preview";
import TetrisScore from "./score";
import {
  BOARD_HEIGHT,
  BOARD_WIDTH,
  GameState,
  TETROMINOES,
  TetrominoType,
  calculateDropTime,
  calculateLevel,
  calculateScore,
  checkCollision,
  clearLines,
  createEmptyBoard,
  randomTetromino,
  rotateTetromino,
} from "@/lib/tetris";

const TetrisGame = () => {
  const { toast } = useToast();
  const isMobile = useMobile();
  const [gameState, setGameState] = useState<GameState>({
    board: createEmptyBoard(),
    currentPiece: randomTetromino(),
    currentPosition: { x: 3, y: 0 },
    nextPiece: randomTetromino(),
    score: 0,
    level: 1,
    lines: 0,
    gameOver: false,
    isPaused: false,
  });
  
  const [dropTime, setDropTime] = useState<number | null>(1000);
  const dropTimeRef = useRef<number | null>(dropTime);
  const gameStateRef = useRef(gameState);
  
  // 更新游戏状态引用
  useEffect(() => {
    gameStateRef.current = gameState;
    dropTimeRef.current = dropTime;
  }, [gameState, dropTime]);

  // 重置游戏
  const resetGame = useCallback(() => {
    setGameState({
      board: createEmptyBoard(),
      currentPiece: randomTetromino(),
      currentPosition: { x: 3, y: 0 },
      nextPiece: randomTetromino(),
      score: 0,
      level: 1,
      lines: 0,
      gameOver: false,
      isPaused: false,
    });
    setDropTime(1000);
    toast({
      title: "游戏开始",
      description: "祝你好运！",
    });
  }, [toast]);

  // 暂停/继续游戏
  const togglePause = useCallback(() => {
    setGameState((prev) => {
      const isPaused = !prev.isPaused;
      setDropTime(isPaused ? null : calculateDropTime(prev.level));
      return { ...prev, isPaused };
    });
  }, []);

  // 更新游戏板
  const updateBoard = useCallback(() => {
    const { currentPiece, currentPosition, board } = gameStateRef.current;
    
    // 创建新的游戏板副本
    const newBoard = board.map(row => [...row]);
    
    // 将当前方块添加到游戏板
    for (let y = 0; y < currentPiece.shape.length; y++) {
      for (let x = 0; x < currentPiece.shape[y].length; x++) {
        if (currentPiece.shape[y][x]) {
          const boardY = currentPosition.y + y;
          const boardX = currentPosition.x + x;
          
          if (boardY >= 0) {
            newBoard[boardY][boardX] = currentPiece.type;
          }
        }
      }
    }
    
    return newBoard;
  }, []);

  // 移动方块
  const moveTetromino = useCallback((x: number, y: number) => {
    if (gameStateRef.current.gameOver || gameStateRef.current.isPaused) return;
    
    const newPosition = {
      x: gameStateRef.current.currentPosition.x + x,
      y: gameStateRef.current.currentPosition.y + y,
    };
    
    if (!checkCollision(gameStateRef.current.board, gameStateRef.current.currentPiece, newPosition)) {
      setGameState(prev => ({
        ...prev,
        currentPosition: newPosition,
      }));
    } else if (y > 0) {
      // 如果向下移动时发生碰撞，则固定方块
      if (gameStateRef.current.currentPosition.y < 1) {
        // 游戏结束
        setGameState(prev => ({
          ...prev,
          gameOver: true,
          isPaused: true,
        }));
        setDropTime(null);
        toast({
          title: "游戏结束",
          description: `最终得分: ${gameStateRef.current.score}`,
          variant: "destructive",
        });
        return;
      }
      
      // 更新游戏板
      const newBoard = updateBoard();
      
      // 检查并清除完整的行
      const { newBoard: clearedBoard, linesCleared } = clearLines(newBoard);
      
      // 计算新的分数和等级
      const newLines = gameStateRef.current.lines + linesCleared;
      const newLevel = calculateLevel(newLines);
      const additionalScore = calculateScore(linesCleared, gameStateRef.current.level);
      
      // 更新游戏状态
      setGameState(prev => ({
        ...prev,
        board: clearedBoard,
        currentPiece: prev.nextPiece,
        currentPosition: { x: 3, y: 0 },
        nextPiece: randomTetromino(),
        score: prev.score + additionalScore,
        level: newLevel,
        lines: newLines,
      }));
      
      // 更新下落速度
      if (newLevel > gameStateRef.current.level) {
        setDropTime(calculateDropTime(newLevel));
        toast({
          title: "升级！",
          description: `当前等级: ${newLevel}`,
        });
      }
      
      // 显示消除行数的提示
      if (linesCleared > 0) {
        toast({
          title: `消除了 ${linesCleared} 行！`,
          description: `+${additionalScore} 分`,
        });
      }
    }
  }, [toast, updateBoard]);

  // 旋转方块
  const rotatePiece = useCallback(() => {
    if (gameStateRef.current.gameOver || gameStateRef.current.isPaused) return;
    
    const rotatedPiece = rotateTetromino(gameStateRef.current.currentPiece);
    
    // 检查旋转后是否会发生碰撞
    if (!checkCollision(gameStateRef.current.board, rotatedPiece, gameStateRef.current.currentPosition)) {
      setGameState(prev => ({
        ...prev,
        currentPiece: rotatedPiece,
      }));
    } else {
      // 尝试墙踢（wall kick）- 如果旋转后碰到墙，尝试向左或向右移动一格
      const kickPositions = [
        { x: gameStateRef.current.currentPosition.x + 1, y: gameStateRef.current.currentPosition.y },
        { x: gameStateRef.current.currentPosition.x - 1, y: gameStateRef.current.currentPosition.y },
        { x: gameStateRef.current.currentPosition.x + 2, y: gameStateRef.current.currentPosition.y },
        { x: gameStateRef.current.currentPosition.x - 2, y: gameStateRef.current.currentPosition.y },
      ];
      
      for (const position of kickPositions) {
        if (!checkCollision(gameStateRef.current.board, rotatedPiece, position)) {
          setGameState(prev => ({
            ...prev,
            currentPiece: rotatedPiece,
            currentPosition: position,
          }));
          break;
        }
      }
    }
  }, []);

  // 快速下落
  const dropTetromino = useCallback(() => {
    if (gameStateRef.current.gameOver || gameStateRef.current.isPaused) return;
    
    setDropTime(50);
  }, []);

  // 恢复正常下落速度
  const releaseDropTetromino = useCallback(() => {
    if (gameStateRef.current.gameOver || gameStateRef.current.isPaused) return;
    
    setDropTime(calculateDropTime(gameStateRef.current.level));
  }, []);

  // 硬下落（直接落到底部）
  const hardDrop = useCallback(() => {
    if (gameStateRef.current.gameOver || gameStateRef.current.isPaused) return;
    
    let newY = gameStateRef.current.currentPosition.y;
    
    while (!checkCollision(
      gameStateRef.current.board,
      gameStateRef.current.currentPiece,
      { x: gameStateRef.current.currentPosition.x, y: newY + 1 }
    )) {
      newY += 1;
    }
    
    setGameState(prev => ({
      ...prev,
      currentPosition: { ...prev.currentPosition, y: newY },
      score: prev.score + (newY - prev.currentPosition.y) * 2, // 硬下落额外加分
    }));
    
    // 立即触发下一次下落，固定方块
    moveTetromino(0, 1);
  }, [moveTetromino]);

  // 自动下落
  useEffect(() => {
    let dropInterval: NodeJS.Timeout | null = null;
    
    if (dropTime && !gameState.gameOver && !gameState.isPaused) {
      dropInterval = setInterval(() => {
        moveTetromino(0, 1);
      }, dropTime);
    }
    
    return () => {
      if (dropInterval) clearInterval(dropInterval);
    };
  }, [dropTime, gameState.gameOver, gameState.isPaused, moveTetromino]);

  // 键盘控制
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (gameStateRef.current.gameOver) {
        if (e.key === 'r' || e.key === 'R') {
          resetGame();
        }
        return;
      }
      
      if (e.key === 'p' || e.key === 'P') {
        togglePause();
        return;
      }
      
      if (gameStateRef.current.isPaused) return;
      
      switch (e.key) {
        case 'ArrowLeft':
          moveTetromino(-1, 0);
          break;
        case 'ArrowRight':
          moveTetromino(1, 0);
          break;
        case 'ArrowDown':
          dropTetromino();
          break;
        case 'ArrowUp':
          rotatePiece();
          break;
        case ' ':
          hardDrop();
          break;
        default:
          break;
      }
    };
    
    const handleKeyUp = (e: KeyboardEvent) => {
      if (gameStateRef.current.gameOver || gameStateRef.current.isPaused) return;
      
      if (e.key === 'ArrowDown') {
        releaseDropTetromino();
      }
    };
    
    window.addEventListener('keydown', handleKeyDown);
    window.addEventListener('keyup', handleKeyUp);
    
    return () => {
      window.removeEventListener('keydown', handleKeyDown);
      window.removeEventListener('keyup', handleKeyUp);
    };
  }, [moveTetromino, rotatePiece, dropTetromino, releaseDropTetromino, hardDrop, resetGame, togglePause]);

  // 渲染游戏
  return (
    <motion.div 
      className="tetris-container w-full"
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      transition={{ duration: 0.5 }}
    >
      <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
        <div className="md:col-span-2">
          <TetrisBoard 
            board={gameState.board}
            currentPiece={gameState.currentPiece}
            currentPosition={gameState.currentPosition}
            gameOver={gameState.gameOver}
            isPaused={gameState.isPaused}
          />
        </div>
        <div className="flex flex-col gap-4">
          <TetrisScore 
            score={gameState.score}
            level={gameState.level}
            lines={gameState.lines}
          />
          <TetrisPreview nextPiece={gameState.nextPiece} />
          <TetrisControls 
            onMoveLeft={() => moveTetromino(-1, 0)}
            onMoveRight={() => moveTetromino(1, 0)}
            onRotate={rotatePiece}
            onSoftDrop={dropTetromino}
            onReleaseSoftDrop={releaseDropTetromino}
            onHardDrop={hardDrop}
            onPause={togglePause}
            onReset={resetGame}
            gameOver={gameState.gameOver}
            isPaused={gameState.isPaused}
            isMobile={isMobile}
          />
        </div>
      </div>
    </motion.div>
  );
};

export default TetrisGame;